package com.kifas.service.dataaccess;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.kifas.entity.BukuHutangEntity;
import com.kifas.entity.HutangEntity;
import com.kifas.entity.SupplierEntity;

@Repository
public class HutangDao {

	@Autowired
	private SessionFactory sessionFactory;

	private static final String ALL_BUKU_HUTANG = "from BukuHutangEntity bh ";
	private static final String BUKU_HUTANG_BY_HUTANG = ALL_BUKU_HUTANG + " where bh.hutang = :hutang";
	private static final String BUKU_HUTANG_BY_ID = ALL_BUKU_HUTANG + " where bh.idBukuHutang = :idBukuHutang";
	private static final String ALL_HUTANG = "from HutangEntity h ";
	private static final String HUTANG_BY_ID = ALL_HUTANG + " where h.idHutang = :idHutang";
	private static final String BUKU_HUTANG_LATEST = BUKU_HUTANG_BY_HUTANG + " order by bh.tanggal desc";
	private static final String HUTANG_BY_SUPPLIER = ALL_HUTANG + " where h.supplier = :supplier";
	private static final String HUTANG_JATUH_TEMPO = ALL_HUTANG + " where h.tanggalJatuhTempo >= :tanggalJatuhTempo";

	public void insert(HutangEntity hutang) throws Exception {
		sessionFactory.getCurrentSession().save(hutang);
		for (BukuHutangEntity bukuHutang : hutang.getBukuHutangs()) {
			insert(bukuHutang);
		}
	}

	public void insert(BukuHutangEntity bukuHutang) throws Exception {
		sessionFactory.getCurrentSession().save(bukuHutang);
	}

	public void update(HutangEntity hutang) throws Exception {
		sessionFactory.getCurrentSession().update(hutang);
	}

	public void update(BukuHutangEntity bukuHutang) throws Exception {
		sessionFactory.getCurrentSession().update(bukuHutang);
	}

	@SuppressWarnings("unchecked")
	public List<HutangEntity> getHutangs() {
		return sessionFactory.getCurrentSession().createQuery(ALL_HUTANG).list();
	}

	@SuppressWarnings("unchecked")
	public List<HutangEntity> getHutangs(Date start, Date end) {
		return sessionFactory.getCurrentSession().createQuery(ALL_HUTANG + " where h.tanggal between :start and :end").setDate("start", start)
				.setDate("end", end).list();
	}

	public HutangEntity getHutang(Long idHutang) {
		return (HutangEntity) sessionFactory.getCurrentSession().createQuery(HUTANG_BY_ID).setLong("idHutang", idHutang).uniqueResult();
	}

	public BukuHutangEntity getBukuHutang(Long idBukuHutang) {
		return (BukuHutangEntity) sessionFactory.getCurrentSession().createQuery(BUKU_HUTANG_BY_ID).setLong("idBukuHutang", idBukuHutang).uniqueResult();
	}
	
	@SuppressWarnings("unchecked")
	public List<BukuHutangEntity> getBukuHutangs(boolean posting) {
		if(posting)
			return sessionFactory.getCurrentSession().createQuery(ALL_BUKU_HUTANG + " where bh.posting = '1'").list();
		else
			return sessionFactory.getCurrentSession().createQuery(ALL_BUKU_HUTANG + " where bh.posting = '0'").list();
	}

	@SuppressWarnings("unchecked")
	public List<HutangEntity> getHutangs(SupplierEntity supplier) {
		return sessionFactory.getCurrentSession().createQuery(HUTANG_BY_SUPPLIER).setEntity("supplier", supplier).list();
	}

	@SuppressWarnings("unchecked")
	public List<HutangEntity> getHutang(int days) {
		Calendar tanggalJatuhTempo = new GregorianCalendar();
		if (days != 0) days = days * -1;
		tanggalJatuhTempo.add(Calendar.DATE, days);
		return sessionFactory.getCurrentSession().createQuery(HUTANG_JATUH_TEMPO).setDate("tanggalJatuhTempo", tanggalJatuhTempo.getTime()).list();
	}

	@SuppressWarnings("unchecked")
	public List<BukuHutangEntity> getBukuHutangs(HutangEntity hutang) {
		return sessionFactory.getCurrentSession().createQuery(BUKU_HUTANG_BY_HUTANG).setEntity("hutang", hutang).list();
	}

	public BukuHutangEntity getLatestBukuHutang(HutangEntity hutang) {
		return (BukuHutangEntity) sessionFactory.getCurrentSession().createQuery(BUKU_HUTANG_LATEST).setEntity("hutang", hutang).list().get(0);
	}

}
